<template>
  <!-- default-expand-all -->
  <div class="easy-tree">
    <div v-if="menu === 'pc' || menu === 'deal'" class="action-btn">
      <el-button size="mini" plain @click="viewHandle">{{ $t('仅查看') }}</el-button>
      <el-button size="mini" plain @click="editHandle">{{ $t('仅编辑') }}</el-button>
      <el-button size="mini" plain @click="resetHandle">{{ $t('重置') }}</el-button>
    </div>
    <!-- <div class="mb10" style="border-bottom: 1px solid rgb(238, 238, 238);padding: 10px;">
      <el-checkbox v-model="deptExpand" @change="handleCheckedTreeExpand($event)">{{ $t('展开/折叠') }}</el-checkbox>
    </div> -->
    <vue-easy-tree
      ref="tree"
      v-loading="loading"
      show-checkbox
      node-key="id"
      :data="menuOptions"
      :check-strictly="true"
      height="calc(100% - 10px)"
      :props="defaultProps"
      :expand-on-click-node="false"
      :default-expanded-keys="expandedKeys"
      :default-checked-keys="checkedList"
      :default-expand-all="expandAll"
      @check="handCheck"
    >
      <span slot-scope="{ node, data }" class="check-tree-node">
        <span>{{ node.label }}</span>
        <template>
          <el-checkbox-group v-if="isRefresh" v-model="perList">
            <el-checkbox v-for="v in data.list" :key="v.id" :label="v.id" @change="onChecked($event, v, data)">{{ v.label }}</el-checkbox>
          </el-checkbox-group>
        </template>
      </span>
    </vue-easy-tree>
  </div>

</template>

<script>
import VueEasyTree from '@wchbrad/vue-easy-tree'
import '@wchbrad/vue-easy-tree/src/assets/index.scss'
import { deepClone, treeToArray } from '@/utils'
export default {
  name: 'ZTree',
  components: {
    VueEasyTree
  },
  props: {
    menuOptions: {
      type: Array,
      default: () => []
    },
    permissionsList: {
      type: Array,
      default: () => []
    },
    checkNodes: {
      type: Array,
      default: () => []
    },
    menu: {
      type: String,
      default: () => ''
    },
    expandAll: {
      type: Boolean,
      default: () => false
    }
  },
  data() {
    return {
      deptExpand: true,
      checkedList: this.checkNodes,
      defaultProps: {
        children: 'children',
        label: 'label'
      },
      isRefresh: true,
      loading: true,
      perList: [],
      treeHeight: '300px'
    }
  },
  computed: {
    expandedKeys() {
      var arr = this.menuOptions.map(item => item.id)
      return arr
    }
  },
  watch: {
    checkNodes: {
      handler(val) {
        this.deptExpand = true
        this.checkedList = []
        this.perList = []
        this.$nextTick(() => {
          this.loading = false
          if (this.$refs.tree?.setCheckedKeys !== undefined) { this.$refs.tree.setCheckedKeys([]) }
          if (val) {
            if (this.menu === 'pc') {
              this.checkedList = val
              var perList = Object.assign([], val)
              var arrs = [...new Set(perList)]
              var permissionsList = this.permissionsList.map(v => v.id)
              this.perList = permissionsList.filter(v => arrs.findIndex(el => el === v) !== -1)
            } else if (this.menu === 'mob') {
              var arr = treeToArray(deepClone(this.menuOptions)).map(item => item.id)
              var mobList = Object.assign([], val)
              var marr = [...new Set(mobList)]
              // console.log(arr, marr)

              this.checkedList = arr.filter(v => marr.findIndex(el => el === v) !== -1)
            } else if (this.menu === 'deal') {
              var treeArr = treeToArray(deepClone(this.menuOptions)).map(item => item.id)
              var dealList = Object.assign([], val)
              var dealLists = [...new Set(dealList)]
              this.checkedList = treeArr.filter(v => dealLists.findIndex(el => el === v) !== -1)
              var permissions = this.permissionsList.map(v => v.id)
              this.perList = permissions.filter(v => dealLists.findIndex(el => el === v) !== -1)
            }
            this.emit()
          }
        })
      },
      deep: true,
      immediate: true
    }
  },
  mounted() {
    // console.log(this)
  },
  methods: {
    emit() {
      // console.log('checkedKeys', this.checkedList, this.perList)
      const perList = [...this.perList, ...this.checkedList]
      var arr = [...new Set(perList)]
      if (this.menu === 'mob') {
        this.$emit('checkedDataMob', arr)
      } else if (this.menu === 'pc') {
        this.$emit('checkedDataPc', arr)
      } else if (this.menu === 'deal') {
        this.$emit('checkedDataDeal', arr)
      }
    },
    handleCheckedTreeExpand(e) { // 展开收起
      this.loading = true

      // console.log(e)
      if (e) {
        for (var i = 0; i < this.$refs.tree.store._getAllNodes().length; i++) {
          this.$refs.tree.store._getAllNodes()[i].expanded = true
        }
      } else {
        for (var j = 0; j < this.$refs.tree.store._getAllNodes().length; j++) {
          this.$refs.tree.store._getAllNodes()[j].expanded = false
        }
      }
      this.$nextTick(() => {
      })
      setTimeout(() => {
        this.loading = false
      }, 1000)
    },
    onChecked(e, node, data) {
      console.log('onChecked', e, node, data)
      node.checked = e
      var result = []
      this.findParent(this.menuOptions, node.id, result)
      // console.log(result)
      result.forEach(v => {
        this.$refs.tree.setChecked(v, true)
      })

      this.isRefresh = false
      this.$nextTick(() => {
        this.isRefresh = true
      })

      var _index = this.perList.indexOf(node.id)
      if (_index !== -1) {
          if (!e) {
            this.perList.splice(_index, 1)
          }
      } else {
        if (e) { this.perList.push(node.id) }
      }
      this.checkedList = this.$refs.tree.getCheckedKeys()
      this.emit()
      this.$forceUpdate()
    },
    // 覆盖原有勾选功能，父与子关联，子与父不关联
    handCheck(data, node) {
      this.hanleCheck(data, node, 'tree')
    },
    hanleCheck(data, node, treeName) {
      // console.log(data, node)
      // console.log('hanleCheck', data, node)

      const _this = this
      // 获取当前节点是否被选中
      const isChecked = _this.$refs[treeName].getNode(data).checked
      // 如果当前节点被选中，则遍历下级子节点并选中，如果当前节点取消选中，则遍历下级节点并取消
      if (isChecked) {
        var result = []
        this.findParent(this.menuOptions, data.id, result)
        // console.log(result)
        result.forEach(v => {
          this.$refs.tree.setChecked(v, true)
        })
        // 判断该节点是否有下级节点，如果有那么遍历设置下级节点为选中
        data.children && data.children.length > 0 && setChildreChecked(data.children, true)
      } else {
        // 如果节点取消选中，则取消该节点下的子节点选中
        data.children && data.children.length > 0 && setChildreChecked(data.children, false)
      }

      function setChildreChecked(node, isChecked) {
        node.forEach(item => {
          item.children && item.children.length > 0 && setChildreChecked(item.children, isChecked)
          // 修改勾选状态
          _this.$refs[treeName].setChecked(item.id, isChecked)
        })
      }
      // 操作权限点
      this.getAllNode(data, isChecked)
      this.checkedList = this.$refs.tree.getCheckedKeys()
      this.emit()
    },
    // 查找所有上级
    findParent(data, id, result) {
      for (const i in data) {
        const item = data[i]
        if (item.id === id) {
          result.unshift(item.id)
          return true
        }
        if (item.children && item.children.length > 0) {
          const ok = this.findParent(item.children, id, result)
          if (ok) {
            result.unshift(item.id)
            return true
          }
        }
      }
      return false
    },
    getAllNode(data, is) {
      var list = data.children || []
      if (list.length > 0) {
        for (let i = 0; i < list.length; i++) {
          var item = list[i]

          if (item.list && item.list.length > 0) {
            // console.log(item.label)
            this.allCheckHandle(item.list, is)
          }
          if (item.children) {
            this.getAllNode(item, is)
          }
        }
      }
      if (data.list && data.list.length > 0) {
        this.allCheckHandle(data.list, is)
      }
      this.$forceUpdate()
    },
    allCheckHandle(list, is) {
      var arrs = list.map(v => v.id)
      if (is) {
        const perList = [...this.perList, ...arrs]
        this.perList = [...new Set(perList)]
      } else {
        this.perList = this.perList.filter(v => arrs.findIndex(el => el === v) === -1)
      }
      this.isRefresh = false
      this.$nextTick(() => {
        this.isRefresh = true
      })
      this.$forceUpdate()
    },
    viewHandle() { // 仅查看，一键全选功能本身，不选中权限
      this.perList = []
      const rootNode = this.$refs.tree.getNode(this.menuOptions[0].id).parent
      travelNodes(rootNode)
      this.checkedList = this.$refs.tree.getCheckedKeys()
      this.emit()
      function travelNodes(tmpRoot) {
        tmpRoot.checked = true
        if (tmpRoot.childNodes.length === 0) {
          return
        } else {
          const tmpChildNoes = tmpRoot.childNodes
          for (let i = 0; i < tmpChildNoes.length; i++) {
            travelNodes(tmpChildNoes[i])
          }
        }
      }
    },
    editHandle() { // 仅编辑，一键全选功能+编辑权限
      this.perList = this.permissionsList.map(v => v.id)
      const rootNode = this.$refs.tree.getNode(this.menuOptions[0].id).parent
      travelNodes(rootNode)
      this.checkedList = this.$refs.tree.getCheckedKeys()
      this.emit()
      function travelNodes(tmpRoot) {
        tmpRoot.checked = true
        if (tmpRoot.childNodes.length === 0) {
          return
        } else {
          const tmpChildNoes = tmpRoot.childNodes
          for (let i = 0; i < tmpChildNoes.length; i++) {
            travelNodes(tmpChildNoes[i])
          }
        }
      }
    },
    resetHandle() { // 重置，清空当前所有选中状态
      this.$refs.tree.setCheckedKeys([])
      this.perList = []
      this.checkedList = []
      this.emit()
    }

  }
}
</script>

<style lang="scss" scoped>
.easy-tree{
  position: relative;
  .action-btn{
    position: absolute;
    right: 10px;
    top: 0;
    z-index: 9;
  }
}
</style>
